/**
 * Copyright 2006 gworks.com.au
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License. (http://www.apache.org/licenses/LICENSE-2.0)
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed 
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for 
 * the specific language governing permissions and limitations under the License.
 *
 * <dhamma-message src="Atisha (11th century Tibetan Buddhist master)">
 * 	The greatest achievement is selflessness. The greatest worth is self-mastery.
 * 	The greatest quality is seeking to serve others. The greatest precept is continual awareness.
 * 	The greatest medicine is the emptiness of everything. The greatest action is not conforming with the worlds ways.
 * 	The greatest magic is transmuting the passions. The greatest generosity is non-attachment.
 * 	The greatest goodness is a peaceful mind. The greatest patience is humility.
 * 	The greatest effort is not concerned with results. The greatest meditation is a mind that lets go.
 * 	The greatest wisdom is seeing through appearances. 
 * </dhamma-message>
 */
package org.javaongems.client;

import java.util.Map;

import org.javaongems.client.rt.io.AsyncCallbackFilter;
import org.javaongems.client.service.GemletConstants;
import org.javaongems.client.service.ResourceBundleRpc;

import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.ServiceDefTarget;

/**
 * <p>Provides the specification for application specific behaviour that is called
 * back by the Gem framework. It is important to realise that GWT/Gem framework 
 * is the container/engine that is executing. The framework delegates to the 
 * Gemlet for only the application specifics.</p>
 * <p>Responsibilities:
 * <ul>
 * 	<li>provision all application specific state and behavior  
 * 	<li>establish connections to system properties
 * 	<li>establish connections to services
 * 	<li>handle failures in a common/repeatable fashion
 * 	<li>construct the application's view, controllers and commands
 * </ul>
 * </p> 
 * 
 * <p>Collaborators:
 * <ul>
 * 	<li> Coordinators - who delegates all application specific bindings to the
 * 						Gemlet
 * 	<li> Widgets - in order to render the bootstrap page's decorations
 * </ul>
 * </p>
 * 
 * @author Ashin Wimalajeewa (ash)
 */
public interface Gemlet extends GemletConstants {
	/**
	 * <p>The application context is the servlet context assigned to the application
	 * by the deployer of the application into a JEE web container.  In GWT 
	 * hosted mode, this value is an empty string (ie. "") as the application is
	 * installed on the root context. 
	 * </p>
	 * <p>
	 * Notes,<br/>
	 * The reason why this is important is because the Gems framework supports
	 * URL friendly/addressable applications where the sub-context and path
	 * information is dynamic.
	 * </p> 
	 * @return - servlet context associated with the application
	 * 
	 * @see Coordinator#getApplImageCtx()
	 * @see Coordinator#getBlankImageUri()
	 */
	public String getApplCtx();
	
	/**
	 * The gem id is a persistent token that is generated from the server
	 * that delivers the GWT entry point page. In a similar fashion to a session id,
	 * the gem id can be used to maintain state in a hybrid ajax/url friendly
	 * style application. Each rendering of a Gem based GWT application must have
	 * a unique gem id. That means that if for eg a firefox user has opened a 
	 * Gem app and they open a link to a "new firefox tab", then a new gem id will
	 * be issued for that tab's rendering. The gem id is typically serialised with
	 * other gem properties.
	 * 
	 * @see #GEM_ID
	 * @see #getGemProperty(String)
	 * @return a unique token to use as the context in client/server dialogues
	 */
	public String getGemId();
	
	/**
	 * Queries the serialised Gem properties that were embedded in the 
	 * GWT bootstrap entry point page.
	 * 
	 * @param prop - the property name to query the value of
	 * @return - the value (null if undefined) associated to the property name
	 * 
	 * @see Coordinator#getGemPropertyAsString(String, String)
	 */
	public Object getGemProperty(String prop);
	
	/**
	 * Queries the server for the resouce bundle associaed with the locale.
	 * <p>
	 * Note, bundle creators should ensure that unicode characters are used in the properties
	 * when required.
	 * 
	 * @param baseName - the qualified name of the resource to look up (using dot notation)
	 * @param locale - if null, then the locale associated with the http servlet request
	 * 				 will be used.
	 * @return the resource bundle as a HashMap
	 * @see ResourceBundle
	 */
	public Map getResourceBundle(String baseName, ResourceBundleRpc.LocaleInfo locale);
	
	/**
	 * Command that decorates a callback with features common to all asynchronous calls. 
	 * Application developers should use this facility to remove "loading" 
	 * status style message on completion of the callback and also manage common service
	 * failures.
	 * 
	 * @param toDecorate - the callback to decorate
	 * @param args - list of application specific arguments used in decoration construction
	 * @return the original callback that has been wrapped
	 * @see Gem#stone
	 * @see org.javaongems.client.rt.handleFailuresCallback
	 * @see org.javaongems.client.form.FormLoadStatusCallback
	 */
	public AsyncCallbackFilter decorateCallback(AsyncCallback toDecorate, Object[] args);
	
	/**
	 * Command that is similar to the Coordinator's openUrl() method but accepts 
	 * application specific parameters to assemble the url prior to forwarding  
	 * the the openUrl() method.
	 * @param args - list of strings to manipulate and assemble a url
	 * 
	 * @see Coordinator#openUrl(String) 
	 * @see org.javaongems.client.Gem#openUrl(String) (please read important notice)
	 */
	public void	openParameterisedUrl(String[] args);

	/**
	 * Query that enables gem components to determine if debug logging is 
	 * activated for this application. 
	 * @return true if debug is enabled for this application
	 * 
	 * @see #log(String, Throwable)
	 * @see Coordinator#log(String)
	 */
	public boolean isDebugEnabled();
	
	/**
	 * Command that logs information to some sort of device that acts as an 
	 * event monitor. In a GWT application this may be a dedicated form or 
	 * just a div tag where the innerhtml is prepended with the log message. 
	 * This method enables the log signals to be forwarded to a user defined 
	 * device.
	 *  
	 * @param msg - message to log
	 * @param err [optional] - exception that was caught with stack trace reference
	 * 
	 * @see #reportStatus(String)
	 * @see #alertMessage(String)
	 */
	public void	log(String msg, Throwable err);
	
	/**
	 * Command used for reporting status to the user. Most visual system have a 
	 * dedicated widget on the outer most container for reporting status to the 
	 * end user. This method enables those reportStatus signals to be forward to 
	 * the appropriate device/widget.
	 * 
	 * @param msg - the message to report (may support html)
	 * 
	 * @see #alertMessage(String)
	 */
	public void	reportStatus(String msg);
	
	/**
	 * Command used to report a erroneous condition to the end user. Alerts are 
	 * messages intended for end-user consumption. This is different from
	 * logs messages which exist for technical analysis/consumption. Like logs, 
	 * alerts should also be available in a visual alert monitor. This method enables
	 * alert signals to be forward to the appropriate device/widget for visually 
	 * display.
	 * 
	 * @param msg - the message to alert (may support html)
	 * 
	 *  @see #log(String, Throwable)
	 *  @see #reportStatus(String)
	 */
	public void alertMessage(String msg);

	/**
	 * Command that handles service failures by reporting alerts and or 
	 * dispatching specific controllers for execution. Depending on your 
	 * service interface and your application behavior, you may well 
	 * find yourself repeating the sample exception handling repeatedly. Hence, by
	 * creating a cookie cutter handling implementation you can reduce duplicating 
	 * exception handling code everytime you invoke a service.
	 *  
	 * @param caught
	 */
	public void handleServiceFailures(Throwable caught);
	
	/**
	 * Command that handles GWT entry point page load failures if any.
	 * The Gems framework supports URL friendly/accessible GWT applications with
	 * dynamic sub contexts and path information. Gems also supports system 
	 * properties being serialised into each GWT bootstrap html page. Implementers
	 * should query exceptional state information from those Gem properties and
	 * then realise the appropriate handling if a server side exception occurred.
	 * <p>It is important to realise that this command will only get executed 
	 * once per Gem entry point on module load. Whilst this method it may appear 
	 * similar to the handlerServiceFailures() method, its origins a very 
	 * different. When a GWT applications is requested, it <b>must</b> send
	 * GWT entry point bootstrap page over the wire in order for the client to 
	 * load. Hence, it cannot be an exception otherwise no scaffoldings will
	 * load. Therefore, page load exceptions are serialised into the page using
	 * Gem properties which are finally queried when all scaffoldings are loaded.
	 * 
	 * @see GemletConstants#GEM_ON_LOAD_EXCEPTION_CLASS
	 * @see GemletConstants#GEM_ON_LOAD_EXCEPTION_CLASS_MSG
	 * @see #getGemProperty(String)
	 */
	public void	handlePageLoadFailureIfAny();

	/**
	 * Google's GWT services approach is a very simple RPC mechanism. Such 
	 * services are accessed via a proxy which needs to be prepared and
	 * possibly cached. Because every application uses different services, only
	 * gemlet implementations can prepare each service correctly. This method
	 * should prepare and cache the async service associated with the service
	 * name. Implementers should use Gem properties to assemble an end point
	 * with the service name.
	 * 
	 * @param serviceName - logical name of the service (eg. "/gems.util.resourcebundle")
	 * @return - an end point that can be cast as (&lt;service-name&gt;Async) object
	 */
	public ServiceDefTarget openService(String serviceName);
	
	/**
	 * Query that returns the fully Gems RPC context with the service name.
	 * @param serviceName - the logical name of the service
	 * @return the end point to use with ServiceDefTarget
	 */
	public String getEndpointForService(String serviceName);
	
	/**
	 * Command used to construct and render the Gemlets view. This method is 
	 * invoked by the coordinator to load all views that decorate
	 * the page on GWT bootstrap. It is called prior to handlePageLoadFailureIfAny()
	 * so that the alert device should already be initialised.
	 */
	public void	initialiseView();
}
